package com.android.support.lib.universal.view.gamepad;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

import com.android.support.lib.universal.R;
import com.android.support.lib.universal.listenner.VirtualKeyListener;

/**
 * 十字键方向键
 * 注意：十字键的宽度和高度等于自身控件的宽带和高度
 *
 * @author 彭治铭
 */
public class CrossKeyView extends View {

    //当前十字按键方向
    private Orientation mOrientation;

    //正常按键
    private Bitmap mNormalBitmap;
    //上方按键
    private Bitmap mUpBitmap;
    //左方按键
    private Bitmap mLeftBitmap;
    //右方按键
    private Bitmap mRightBitmap;
    //下方按键
    private Bitmap mDownBitmap;
    private int mWidth;
    private int mHeight;
    //位图偏移左边的位置
    private int paddingLeft = 0;
    //位图偏移顶部的位置
    private int paddingTop = 0;

    private KeyEventTask mKeyEventTask;

    private boolean mIsStartKeyEvent = false;

    private VirtualKeyListener mVirtualKeyListener;

    private Paint mPaint;

    public CrossKeyView(Context context) {
        this(context, null);
    }

    public CrossKeyView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CrossKeyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mOrientation = Orientation.O_NORMAL;
    }

    //设置十字按键监听事件
    public void setVirtualKeyListener(VirtualKeyListener virtualKeyListener) {
        mVirtualKeyListener = virtualKeyListener;
    }

    @Override
    public void layout(int left, int top, int right, int bottom) {

        int width = right - left;
        int height = bottom - top;

        width = width > height ? height : width;
        measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY));

        //设置各个按键的图标
        if (null == mNormalBitmap) {
            mWidth = right - left;
            mHeight = bottom - top;
            mWidth = mWidth - 2 * paddingLeft;
            mHeight = mHeight - 2 * paddingLeft;
            Resources res = getResources();
            mNormalBitmap = BitmapFactory.decodeResource(res,
                    R.drawable.lib_gamepad_mnormalbitmap);
            mNormalBitmap = Bitmap.createScaledBitmap(mNormalBitmap, mWidth,
                    mWidth, true);
            mUpBitmap = BitmapFactory.decodeResource(res, R.drawable.lib_gamepad_mupbitmap);
            mUpBitmap = Bitmap.createScaledBitmap(mUpBitmap, mWidth, mWidth,
                    true);
            mLeftBitmap = BitmapFactory.decodeResource(res, R.drawable.lib_gamepad_mleftbitmap);
            mLeftBitmap = Bitmap.createScaledBitmap(mLeftBitmap, mWidth,
                    mWidth, true);
            mRightBitmap = BitmapFactory
                    .decodeResource(res, R.drawable.lib_gamepad_mrightbitmap);
            mRightBitmap = Bitmap.createScaledBitmap(mRightBitmap, mWidth,
                    mWidth, true);
            mDownBitmap = BitmapFactory.decodeResource(res, R.drawable.lib_gamepad_mdownbitmap);
            mDownBitmap = Bitmap.createScaledBitmap(mDownBitmap, mWidth,
                    mWidth, true);
        }
        super.layout(left, top, right, bottom);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        float x = event.getX();
        float y = event.getY();

        double angle1 = Math.atan(x / y);
        double angle2 = Math.atan((mHeight + 2 * paddingLeft - y) / x);

        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_POINTER_DOWN:
                return false;
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:

                double PI_1_4 = Math.PI / 4;

                if (null == mKeyEventTask) {
                    mKeyEventTask = new KeyEventTask();
                    mKeyEventTask.start();
                    mIsStartKeyEvent = true;
                }
                if (angle1 < PI_1_4 && angle2 < PI_1_4) {
                    mOrientation = Orientation.O_DOWN;
                    mKeyEventTask.setKeyCode(GamepadConfig.KEY_CODE_DOWN);
                } else if (angle1 < PI_1_4 && angle2 > PI_1_4) {
                    mOrientation = Orientation.O_LEFT;
                    mKeyEventTask.setKeyCode(GamepadConfig.KEY_CODE_LEFT);
                } else if (angle1 > PI_1_4 && angle2 < PI_1_4) {
                    mKeyEventTask.setKeyCode(GamepadConfig.KEY_CODE_RIGHT);
                    mOrientation = Orientation.O_RIGHT;
                } else if (angle1 > PI_1_4 && angle2 > PI_1_4) {
                    mKeyEventTask.setKeyCode(GamepadConfig.KEY_CODE_UP);
                    mOrientation = Orientation.O_UP;
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
                return false;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                mOrientation = Orientation.O_NORMAL;
                mIsStartKeyEvent = false;
                mKeyEventTask = null;
                break;
        }

        invalidate();
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        switch (mOrientation) {
            case O_NORMAL:
                canvas.drawBitmap(mNormalBitmap, paddingLeft, paddingTop, mPaint);
                break;
            case O_LEFT:
                canvas.drawBitmap(mLeftBitmap, paddingLeft, paddingTop, mPaint);
                break;
            case O_RIGHT:
                canvas.drawBitmap(mRightBitmap, paddingLeft, paddingTop, mPaint);
                break;
            case O_UP:
                canvas.drawBitmap(mUpBitmap, paddingLeft, paddingTop, mPaint);
                break;
            case O_DOWN:
                canvas.drawBitmap(mDownBitmap, paddingLeft, paddingTop, mPaint);
                break;
            case O_UP_LEFT:
                break;
            case O_UP_RIGHT:
                break;
            case O_DOWN_LEFT:
                break;
            case O_DOWN_RIGHT:
                break;
        }
        super.onDraw(canvas);
    }

    //按键事件，每个按键点击都会调用setKeyCode()方法
    class KeyEventTask extends Thread {

        private int mKeyCode;
        private int mKeyCode2;

        public void setKeyCode(int keyCode) {
            mKeyCode2 = keyCode;
            if (mKeyCode == 0) {
                mKeyCode = mKeyCode2;
                //震动音效
                GamepadConfig.STYLE();
            }
            if (mKeyCode != mKeyCode2) {
                //震动音效
                GamepadConfig.STYLE();
            }
        }

        @Override
        public void run() {
            while (mIsStartKeyEvent) {

                if (mKeyCode != 0) {

                    if (mKeyCode != mKeyCode2) {

                        final int keycode = mKeyCode;

                        if (mVirtualKeyListener != null) {
                            post(new Runnable() {
                                @Override
                                public void run() {
                                    mVirtualKeyListener
                                            .onKeyEvent(new KeyEvent(
                                                    KeyEvent.ACTION_UP, keycode));
                                }
                            });
                        }

                        mKeyCode = mKeyCode2;
                    } else {
                        if (mVirtualKeyListener != null) {
                            post(new Runnable() {
                                @Override
                                public void run() {
                                    mVirtualKeyListener
                                            .onKeyEvent(new KeyEvent(
                                                    KeyEvent.ACTION_DOWN,
                                                    mKeyCode));
                                }
                            });
                        }
                    }
                }

                try {
                    Thread.sleep(40);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (mVirtualKeyListener != null) {
                post(new Runnable() {
                    @Override
                    public void run() {
                        mVirtualKeyListener.onKeyEvent(new KeyEvent(
                                KeyEvent.ACTION_UP, mKeyCode));
                    }
                });
            }
        }
    }

    public enum Orientation {
        O_NORMAL, O_UP, O_LEFT, O_RIGHT, O_DOWN, O_UP_LEFT, O_UP_RIGHT, O_DOWN_LEFT, O_DOWN_RIGHT
    }

}
